<?php
/**
 * 控制器类
 *
 * @copyright Copyright (c) 2008 www.eefocus.com
 * @author kokko<kokko313@gmail.com>
 * @package com
 * @subpackage eefocus
 * @version 1.0 2007-7-30
 */
class Action{
	/**
	 * 视图对象
	 *
	 * @access public
	 * @var object
	 */
	public $_view;
	
	/**
	 * 视图显示的内容
	 *
	 * @access protected
	 */
	protected $_data;
	
	/**
	 * 当前view模版
	 *
	 * @access protected
	 */
	protected $_template;

	/**
	 * 当前view模版缓存ID
	 *
	 * @access protected
	 */
	protected $_cacheId = null;

	/**
	 * 错误信息
	 * 
	 * @var mix
	 * @acess protected
	 */
	protected $_error;
	
	/**
	 * 是否自动显示模板
	 * 
	 * @var bool
	 * @acess protected
	 */
	protected $_autoDisplay = true;

	/**
	 * 构造函数
	 *
	 */
	public function __construct(){
		if( !isset( $this->_view ) )
			$this->_view = getView();
	}

	/**
     * 取出当前项目目录下的模型类
	 *
	 * @access public 
	 * @static
     * @param string $model 模型
     * @return boolean
     */
	public static function loadModel( $model ){
		static $modelCache;
		if( isset( $modelCache[$model] ) )
			return $modelCache[$model];
		$className = strrchr( $model,'.' );
		$className = !empty( $className ) ? str_replace( '.','',$className ) : $model;
		$trueClassName = conf( 'MODEL_CLASS_PREFIX' ).$className.conf('MODEL_CLASS_SUFFIX');
		$claPacke = str_replace( $className.".t",$trueClassName,$model.".t" );
		//加载当前项目Lib目录下的Model
		if( import( $claPacke,APP_PATH."/Lib" )===false ){
			throwException( lang('_CLASS_NOT_LOAD' ) );
		}
		$modelCache[$model] = new $trueClassName();
		return $modelCache[$model]; 
	}
	
	/**
     * 取出当前项目目录下的模型类
	 *
	 * @access public 
	 * @static
     * @param string $action 动作
     * @return boolean
     */
	public static function loadAction( $action ){
		static $cache;
		if( isset( $cache[$action] ) )
			return $cache[$action];
		$className = strrchr( $action,'.' );
		$className = !empty( $className ) ? str_replace( '.','',$className ) : $action;
		$trueClassName = conf( 'CONTROL_PREFIX' ).$className.conf('CONTROL_SUFFIX');
		$claPacke = str_replace( $className.".t",$trueClassName,$action.".t" );
		if( import( $claPacke,APP_PATH."/Action" )===false ){
			throwException( lang('_CLASS_NOT_LOAD' ) );
		}
		$modelCache[$action] = new $trueClassName();
		return $modelCache[$action];
	}

	/**
     * 检查当前模块下的操作是否有权限访问
	 *
	 * @access public 
	 * @param string $mod 模块
     * @return boolean
     */
	public function checkAuth( $mod ){
		//普通用户
		$mod = trim( $mod );
		$mod = strtolower( $mod );
		if( !empty( $_SESSION['UserType'] ) ){
			//用户组是1，超级管理组
			if( $_SESSION['UserType']==1 ){
				return true;
			}elseif( isset( $_SESSION['UserPower'] ) && in_array( $mod,$_SESSION['UserPower'] ) ){//如果有权限的session
				return true;
			}
		}
		$this->_error = lang( '_VALID_ACCESS_' );
		return false;
	}
	
	/**
     * 执行动作
	 *
	 * @access public 
     * @param string $action 动作
     * @return boolean
     */
	public function exec( $action ){
		$orAction = $action;
		$action = conf( 'ACTION_PREFIX' ).$action.conf( 'ACTION_SUFFIX' );
		//动作存在
		if( method_exists( $this,$action ) ){
			//执行操作
			$this->$action();
			//为模版赋值
			if( isset( $this->_data ) ){
				foreach( $this->_data as $key=>$val ){
					$this->assign( $key,$val );
				}
			}
			$GLOBALS['_execTime'] = microtime(TRUE);
			//自动显示模版
			if( $this->_autoDisplay ){
				$this->display();
			}
			$GLOBALS['_endTime'] = microtime(TRUE);
		}else{//动作不存在
			$this->__empty();
		}
	}

	 /**
      * 操作信息跳转的快捷方法
	  *
      * @access public 
      * @param string $errorMsg 错误信息
      * @return void 
      */
    public function showMessage( $msg,$redirct=null ) 
    {
		$div = "\n";
		switch( conf( 'OUT_PUT_FORMAT' ) ){
			case 'html':
				$this->assign( 'message',$msg );
				$this->assign( 'redirct',$redirct );
				$this->display( 'Message.html' );
				break;
			case 'xml':
				$this->assign( 'message',$msg );
				$this->assign( 'redirct',$redirct );
				$this->display( 'Message.xml' );
				break;
			case 'json':
				$data['message'] = $msg;
				$data['redirct'] = $redirct;
				echo json_encode( $data );
				break;
			case 'ajax':
			case 'js':
				$div = "[js]";
			default:
				$data['message'] = $msg;
				$data['redirct'] = $redirct;
				echo implode( $div,$data );
				echo $div."\n";
		}
		exit();
    }

	/**
	 * 表单验证
	 *
	 * @param mix $valName -验证配置（string or array）
	 * @param array $data - 待验证的数据
	 * @return array
	 * @access public
	 */
	public function validate( $valName,$data = null ){
		static $validateCache = null;
		if( is_string($valName ) ){
			if( isset( $validateCache[$valName] ) ){
				$vals = $validateCache[$formName];
			}else{
				$valName = strtolower( $valName );
				$valFile = conf('DATA_VALIDATE')."/form.{$valName}.php";
				if( file_exists( $valFile ) )
					$vals = include ( $valFile );
				else 
					return true;
				$validateCache[$valName] = $vals;
			}
		}else{
			$vals = $valName;
		}
		if( empty( $data ) ) $data = $_POST;
		/*
		array(field,rule,message,condition,append)
		field rule message 必须
		condition 验证条件：0 存在字段就验证 1 必须验证 2 值不为空的时候验证 默认为2
		append 附加规则 :function confirm regex equal in unique默认为regex
		*/
		foreach( $vals as $key=>$val ){
			//必须验证
			switch( $val[3] ){
				case 0:	//字段值存在就验证
					if( isset($data[$val[0]]) && !$this->validationField( $data,$val )  ){
						$this->_error = $val[2];
						return false;
					}
					break;
				case 1: //必须验证
					if( !$this->validationField( $data,$val ) ){
						$this->_error = $val[2];
						return false;
					}
					break;
				case 2:	//值不为空时验证
				default:
					if( '' != trim($data[$val[0]]) && !$this->validationField( $data,$val )  ){
						$this->_error = $val[2];
						return false;
					}
					break;
			}
		}
		return true;
	}

	/**
	 * 取得模板
	 *
	 * @acsess private
	 * @return string
	 */
	protected function getTemplate(){
		if( !empty( $this->_template ) )
			return VIEW_PATH.$this->_template;
		$out = conf( 'OUT_PUT_FORMAT' );
		switch( $out ){
			case 'xml':
				return VIEW_PATH.MODULE_NAME.'_'.ACTION_NAME.'.xml';
				break;
			case 'html':
				return VIEW_PATH.MODULE_NAME.'_'.ACTION_NAME.'.html';
				break;
		}
	}

	/**
     * 为模版变量赋值
	 *
     * @param string $key 变量名
     * @param mix $val 变量值
	 * @access public 
     */
	public function assign( $key,$val ){
		$this->_view->assign( $key,$val );
	}
	
	/**
     * 显示模版
	 *
     * @param string $template 模版名
	 * @param string $cacheId 缓存ID
	 * @access public 
     */
	public function display( $template=null,$cacheId = null ){
		//记录是否已经自定义显示了模板
		static $is_displayed = false;	
		if( $is_displayed )
			return;
		$template = !empty( $template ) ? $template : $this->getTemplate();
		$cacheId = !empty( $cacheId ) ? $cacheId : $this->_cacheId;
		$is_displayed = true;
		$this->_view->display( $template,$cacheId );
	}
	
	/**
     * 默认方法
	 * 当没有Action方法存在时，调用该方法
	 *
	 * @access protected 
     * @return void
     */
	protected function __empty(){
		$this->showMessage( lang( '_ACTION_NOT_EXIST_' ) );
	}
	
	/**
     * 根据验证因子验证字段
	 *
	 * @access protected 
     * @param array $data 创建数据
     * @param string $val 验证规则
     * @return boolean
     */
	protected function validationField( $data,$val ){
		$type = isset( $val[4] ) ? strtolower( $val[4] ) : '';
		switch( $type ) {
			case 'function':	//使用函数进行验证
				if(function_exists($val[1]) && !$val[1]($data[$val[0]])) {
					return false;
				}
				break;
			case 'method':		//调用方法进行验证
				if(method_exists( $this,$val[1] ) && !$this->{$val[1]}($data[$val[0]]) ) {
					return false;
				}
				break;
			case 'confirm':		//验证两个字段是否相同
				if($data[$val[0]] != $data[$val[1]] ) {
					return false;
				}
				break;
			case 'in':			//验证是否在某个数组范围之内
				if(!@in_array($data[$val[0]],$data[$val[1]]) ) {
					return false;
				}
				break;
			case 'equal':		//验证是否等于某个值
				if($data[$val[0]] != $val[1]) {
					return false;
				}
				break;
			case 'regex':		//默认使用正则验证可以使用验证类中定义的验证名称
			default:
				if( !Validation::check($data[$val[0]],$val[1])) {
					return false;
				}
				break;
		}
		return true;
	}
}//end class
?>